home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 1 / QRZ Ham Radio Callsign Database - December 1993.iso / ucsd / packet / tcpip / sys5 / iscwmpst.z / iscwmpst / tcp / src / tcpin.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-05-10  |  23.6 KB  |  892 lines

  1. /* @(#) $Header: tcpin.c,v 1.7 91/05/09 07:38:58 deyke Exp $ */
  2.  
  3. /* Process incoming TCP segments. Page number references are to ARPA RFC-793,
  4.  * the TCP specification.
  5.  *
  6.  * Copyright 1991 Phil Karn, KA9Q
  7.  */
  8. #include "global.h"
  9. #include "timer.h"
  10. #include "mbuf.h"
  11. #include "netuser.h"
  12. #include "internet.h"
  13. #include "tcp.h"
  14. #include "icmp.h"
  15. #include "iface.h"
  16. #include "ip.h"
  17.  
  18. static void update __ARGS((struct tcb *tcb,struct tcp *seg,int length));
  19. static void proc_syn __ARGS((struct tcb *tcb,int tos,struct tcp *seg));
  20. static void add_reseq __ARGS((struct tcb *tcb,int tos,struct tcp *seg,
  21.     struct mbuf *bp,int length));
  22. static void get_reseq __ARGS((struct tcb *tcb,char *tos,struct tcp *seq,
  23.     struct mbuf **bp,int16 *length));
  24. static int trim __ARGS((struct tcb *tcb,struct tcp *seg,struct mbuf **bpp,
  25.     int16 *length));
  26. static int in_window __ARGS((struct tcb *tcb,int32 seq));
  27.  
  28. /* This function is called from IP with the IP header in machine byte order,
  29.  * along with a mbuf chain pointing to the TCP header.
  30.  */
  31. void
  32. tcp_input(iface,ip,bp,rxbroadcast)
  33. struct iface *iface;    /* Incoming interface (ignored) */
  34. struct mbuf *bp;        /* Data field, if any */
  35. struct ip *ip;          /* IP header */
  36. int rxbroadcast;        /* Incoming broadcast - discard if true */
  37. {
  38.     struct tcb *ntcb;
  39.     register struct tcb *tcb;       /* TCP Protocol control block */
  40.     struct tcp seg;                 /* Local copy of segment header */
  41.     struct connection conn;         /* Local copy of addresses */
  42.     struct pseudo_header ph;        /* Pseudo-header for checksumming */
  43.     int hdrlen;                     /* Length of TCP header */
  44.     int16 length;
  45.  
  46.     if(bp == NULLBUF)
  47.         return;
  48.  
  49.     tcpInSegs++;
  50.     if(rxbroadcast){
  51.         /* Any TCP packet arriving as a broadcast is
  52.          * to be completely IGNORED!!
  53.          */
  54.         free_p(bp);
  55.         return;
  56.     }
  57.     length = ip->length - IPLEN - ip->optlen;
  58.     ph.source = ip->source;
  59.     ph.dest = ip->dest;
  60.     ph.protocol = ip->protocol;
  61.     ph.length = length;
  62.     if(cksum(&ph,bp,length) != 0){
  63.         /* Checksum failed, ignore segment completely */
  64.         tcpInErrs++;
  65.         free_p(bp);
  66.         return;
  67.     }
  68.     /* Form local copy of TCP header in host byte order */
  69.     if((hdrlen = ntohtcp(&seg,&bp)) < 0){
  70.         /* TCP header is too small */
  71.         free_p(bp);
  72.         return;
  73.     }
  74.     length -= hdrlen;
  75.  
  76.     /* Fill in connection structure and find TCB */
  77.     conn.local.address = ip->dest;
  78.     conn.local.port = seg.dest;
  79.     conn.remote.address = ip->source;
  80.     conn.remote.port = seg.source;
  81.  
  82.     if((tcb = lookup_tcb(&conn)) == NULLTCB){
  83.         /* If this segment doesn't carry a SYN, reject it */
  84.         if(!seg.flags.syn){
  85.             free_p(bp);
  86.             reset(ip,&seg);
  87.             return;
  88.         }
  89.         /* See if there's a TCP_LISTEN on this socket with
  90.          * unspecified remote address and port
  91.          */
  92.         conn.remote.address = 0;
  93.         conn.remote.port = 0;
  94.         if((tcb = lookup_tcb(&conn)) == NULLTCB){
  95.             /* Nope, try unspecified local address too */
  96.             conn.local.address = 0;
  97.             if((tcb = lookup_tcb(&conn)) == NULLTCB){
  98.                 /* No LISTENs, so reject */
  99.                 free_p(bp);
  100.                 reset(ip,&seg);
  101.                 return;
  102.             }
  103.         }
  104.         /* We've found an server listen socket, so clone the TCB */
  105.         if(tcb->flags.clone){
  106.             ntcb = (struct tcb *)mallocw(sizeof (struct tcb));
  107.             ASSIGN(*ntcb,*tcb);
  108.             tcb = ntcb;
  109.             tcb->timer.arg = tcb;
  110.             /* Put on list */
  111.             tcb->next = Tcbs;
  112.             Tcbs = tcb;
  113.         }
  114.         /* Put all the socket info into the TCB */
  115.         tcb->conn.local.address = ip->dest;
  116.         tcb->conn.remote.address = ip->source;
  117.         tcb->conn.remote.port = seg.source;
  118.     }
  119.     tcb->flags.congest = ip->flags.congest;
  120.     /* Do unsynchronized-state processing (p. 65-68) */
  121.     switch(tcb->state){
  122.     case TCP_CLOSED:
  123.         free_p(bp);
  124.         reset(ip,&seg);
  125.         return;
  126.     case TCP_LISTEN:
  127.         if(seg.flags.rst){
  128.             free_p(bp);
  129.             return;
  130.         }
  131.         if(seg.flags.ack){
  132.             free_p(bp);
  133.             reset(ip,&seg);
  134.             return;
  135.         }
  136.         if(seg.flags.syn){
  137.             /* (Security check is bypassed) */
  138.             /* page 66 */
  139.             proc_syn(tcb,ip->tos,&seg);
  140.             send_syn(tcb);
  141.             setstate(tcb,TCP_SYN_RECEIVED);
  142.             if(length != 0 || seg.flags.fin) {
  143.                 /* Continue processing if there's more */
  144.                 break;
  145.             }
  146.             tcp_output(tcb);
  147.         }
  148.         free_p(bp);     /* Unlikely to get here directly */
  149.         return;
  150.     case TCP_SYN_SENT:
  151.         if(seg.flags.ack){
  152.             if(!seq_within(seg.ack,tcb->iss+1,tcb->snd.nxt)){
  153.                 free_p(bp);
  154.                 reset(ip,&seg);
  155.                 return;
  156.             }
  157.         }
  158.         if(seg.flags.rst){      /* p 67 */
  159.             if(seg.flags.ack){
  160.                 /* The ack must be acceptable since we just checked it.
  161.                  * This is how the remote side refuses connect requests.
  162.                  */
  163.                 close_self(tcb,RESET);
  164.             }
  165.             free_p(bp);
  166.             return;
  167.         }
  168.         /* (Security check skipped here) */
  169.         /* Check incoming precedence; it must match if there's an ACK */
  170.         if(seg.flags.ack && PREC(ip->tos) != PREC(tcb->tos)){
  171.             free_p(bp);
  172.             reset(ip,&seg);
  173.             return;
  174.         }
  175.         if(seg.flags.syn){
  176.             proc_syn(tcb,ip->tos,&seg);
  177.             if(seg.flags.ack){
  178.                 /* Our SYN has been acked, otherwise the ACK
  179.                  * wouldn't have been valid.
  180.                  */
  181.                 update(tcb,&seg,length);
  182.                 setstate(tcb,TCP_ESTABLISHED);
  183.             } else {
  184.                 setstate(tcb,TCP_SYN_RECEIVED);
  185.             }
  186.             if(length != 0 || seg.flags.fin) {
  187.                 break;          /* Continue processing if there's more */
  188.             }
  189.             tcp_output(tcb);
  190.         } else {
  191.             free_p(bp);     /* Ignore if neither SYN or RST is set */
  192.         }
  193.         return;
  194.     }
  195.     /* We reach this point directly in any synchronized state. Note that
  196.      * if we fell through from LISTEN or SYN_SENT processing because of a
  197.      * data-bearing SYN, window trimming and sequence testing "cannot fail".
  198.      */
  199.  
  200.     /* Trim segment to fit receive window. */
  201.     if(trim(tcb,&seg,&bp,&length) == -1){
  202.         /* Segment is unacceptable */
  203.         if(!seg.flags.rst){     /* NEVER answer RSTs */
  204.             /* In SYN_RECEIVED state, answer a retransmitted SYN
  205.              * with a retransmitted SYN/ACK.
  206.              */
  207.             if(tcb->state == TCP_SYN_RECEIVED)
  208.                 tcb->snd.ptr = tcb->snd.una;
  209.             tcb->flags.force = 1;
  210.             tcp_output(tcb);
  211.         }
  212.         return;
  213.     }
  214.     /* If segment isn't the next one expected, and there's data
  215.      * or flags associated with it, put it on the resequencing
  216.      * queue, ACK it and return.
  217.      *
  218.      * Processing the ACK in an out-of-sequence segment without
  219.      * flags or data should be safe, however.
  220.      */
  221.     if(seg.seq != tcb->rcv.nxt
  222.      && (length != 0 || seg.flags.syn || seg.flags.fin)){
  223.         add_reseq(tcb,ip->tos,&seg,bp,length);
  224.         tcb->flags.force = 1;
  225.         tcp_output(tcb);
  226.         return;
  227.     }
  228.     /* This loop first processes the current segment, and then
  229.      * repeats if it can process the resequencing queue.
  230.      */
  231.     for(;;){
  232.         /* We reach this point with an acceptable segment; all data and flags
  233.          * are in the window, and the starting sequence number equals rcv.nxt
  234.          * (p. 70)
  235.          */
  236.         if(seg.flags.rst){
  237.             if(tcb->state == TCP_SYN_RECEIVED
  238.              && !tcb->flags.clone && !tcb->flags.active){
  239.                 /* Go back to listen state only if this was
  240.                  * not a cloned or active server TCB
  241.                  */
  242.                 setstate(tcb,TCP_LISTEN);
  243.             } else {
  244.                 close_self(tcb,RESET);
  245.             }
  246.             free_p(bp);
  247.             return;
  248.         }
  249.         /* (Security check skipped here) p. 71 */
  250.         /* Check for precedence mismatch or erroneous extra SYN */
  251.         if(PREC(ip->tos) != PREC(tcb->tos) || seg.flags.syn){
  252.             free_p(bp);
  253.             reset(ip,&seg);
  254.             return;
  255.         }
  256.         /* Check ack field p. 72 */
  257.         if(!seg.flags.ack){
  258.             free_p(bp);     /* All segments after synchronization must have ACK */
  259.             return;
  260.         }
  261.         /* Process ACK */
  262.         switch(tcb->state){
  263.         case TCP_SYN_RECEIVED:
  264.             if(seq_within(seg.ack,tcb->snd.una+1,tcb->snd.nxt)){
  265.                 update(tcb,&seg,length);
  266.                 setstate(tcb,TCP_ESTABLISHED);
  267.             } else {
  268.                 free_p(bp);
  269.                 reset(ip,&seg);
  270.                 return;
  271.             }
  272.             break;
  273.         case TCP_ESTABLISHED:
  274.         case TCP_CLOSE_WAIT:
  275.             update(tcb,&seg,length);
  276.             break;
  277.         case TCP_FINWAIT1:      /* p. 73 */
  278.             update(tcb,&seg,length);
  279.             if(tcb->sndcnt == 0){
  280.                 /* Our FIN is acknowledged */
  281.                 setstate(tcb,TCP_FINWAIT2);
  282.             }
  283.             break;
  284.         case TCP_FINWAIT2:
  285.             update(tcb,&seg,length);
  286.             break;
  287.         case TCP_CLOSING:
  288.             update(tcb,&seg,length);
  289.             if(tcb->sndcnt == 0){
  290.                 /* Our FIN is acknowledged */
  291.                 setstate(tcb,TCP_TIME_WAIT);
  292.                 set_timer(&tcb->timer,MSL2*1000L);
  293.                 start_timer(&tcb->timer);
  294.             }
  295.             break;
  296.         case TCP_LAST_ACK:
  297.             update(tcb,&seg,length);
  298.             if(tcb->sndcnt == 0){
  299.                 /* Our FIN is acknowledged, close connection */
  300.                 close_self(tcb,NORMAL);
  301.                 return;
  302.             }
  303.             break;
  304.         case TCP_TIME_WAIT:
  305.             start_timer(&tcb->timer);
  306.             break;
  307.         }
  308.  
  309.         /* (URGent bit processing skipped here) */
  310.  
  311.         /* Process the segment text, if any, beginning at rcv.nxt (p. 74) */
  312.         if(length != 0){
  313.             switch(tcb->state){
  314.             case TCP_SYN_RECEIVED:
  315.             case TCP_ESTABLISHED:
  316.             case TCP_FINWAIT1:
  317.             case TCP_FINWAIT2:
  318.                 /* Place on receive queue */
  319.                 append(&tcb->rcvq,bp);
  320.                 tcb->rcvcnt += length;
  321.                 tcb->rcv.nxt += length;
  322.                 tcb->rcv.wnd -= length;
  323.                 tcb->flags.force = 1;
  324.                 /* Notify user */
  325.                 if(tcb->r_upcall)
  326.                     (*tcb->r_upcall)(tcb,tcb->rcvcnt);
  327.                 break;
  328.             default:
  329.                 /* Ignore segment text */
  330.                 free_p(bp);
  331.                 break;
  332.             }
  333.         }
  334.         /* process FIN bit (p 75) */
  335.         if(seg.flags.fin){
  336.             tcb->flags.force = 1;   /* Always respond with an ACK */
  337.  
  338.             switch(tcb->state){
  339.             case TCP_SYN_RECEIVED:
  340.             case TCP_ESTABLISHED:
  341.                 tcb->rcv.nxt++;
  342.                 setstate(tcb,TCP_CLOSE_WAIT);
  343.                 break;
  344.             case TCP_FINWAIT1:
  345.                 tcb->rcv.nxt++;
  346.                 if(tcb->sndcnt == 0){
  347.                     /* Our FIN has been acked; bypass TCP_CLOSING state */
  348.                     setstate(tcb,TCP_TIME_WAIT);
  349.                     set_timer(&tcb->timer,MSL2*1000L);
  350.                     start_timer(&tcb->timer);
  351.                 } else {
  352.                     setstate(tcb,TCP_CLOSING);
  353.                 }
  354.                 break;
  355.             case TCP_FINWAIT2:
  356.                 tcb->rcv.nxt++;
  357.                 setstate(tcb,TCP_TIME_WAIT);
  358.                 set_timer(&tcb->timer,MSL2*1000L);
  359.                 start_timer(&tcb->timer);
  360.                 break;
  361.             case TCP_CLOSE_WAIT:
  362.             case TCP_CLOSING:
  363.             case TCP_LAST_ACK:
  364.                 break;          /* Ignore */
  365.             case TCP_TIME_WAIT:     /* p 76 */
  366.                 start_timer(&tcb->timer);
  367.                 break;
  368.             }
  369.             /* Call the client again so he can see EOF */
  370.             if(tcb->r_upcall)
  371.                 (*tcb->r_upcall)(tcb,tcb->rcvcnt);
  372.         }
  373.         /* Scan the resequencing queue, looking for a segment we can handle,
  374.          * and freeing all those that are now obsolete.
  375.          */
  376.         while(tcb->reseq != NULLRESEQ && seq_ge(tcb->rcv.nxt,tcb->reseq->seg.seq)){
  377.             get_reseq(tcb,&ip->tos,&seg,&bp,&length);
  378.             if(trim(tcb,&seg,&bp,&length) == 0)
  379.                 goto gotone;
  380.             /* Segment is an old one; trim has freed it */
  381.         }
  382.         break;
  383. gotone: ;
  384.     }
  385.     tcp_output(tcb);        /* Send any necessary ack */
  386. }
  387.  
  388. /* Process an incoming ICMP response */
  389. void
  390. tcp_icmp(icsource,source,dest,type,code,bpp)
  391. int32 icsource;                 /* Sender of ICMP message (not used) */
  392. int32 source;                   /* Original IP datagram source (i.e. us) */
  393. int32 dest;                     /* Original IP datagram dest (i.e., them) */
  394. char type,code;                 /* ICMP error codes */
  395. struct mbuf **bpp;              /* First 8 bytes of TCP header */
  396. {
  397.     struct tcp seg;
  398.     struct connection conn;
  399.     register struct tcb *tcb;
  400.  
  401.     /* Extract the socket info from the returned TCP header fragment
  402.      * Note that since this is a datagram we sent, the source fields
  403.      * refer to the local side.
  404.      */
  405.     ntohtcp(&seg,bpp);
  406.     conn.local.port = seg.source;
  407.     conn.remote.port = seg.dest;
  408.     conn.local.address = source;
  409.     conn.remote.address = dest;
  410.     if((tcb = lookup_tcb(&conn)) == NULLTCB)
  411.         return; /* Unknown connection, ignore */
  412.  
  413.     /* Verify that the sequence number in the returned segment corresponds
  414.      * to something currently unacknowledged. If not, it can safely
  415.      * be ignored.
  416.      */
  417.     if(!seq_within(seg.seq,tcb->snd.una,tcb->snd.nxt))
  418.         return;
  419.  
  420.     /* Destination Unreachable and Time Exceeded messages never kill a
  421.      * connection; the info is merely saved for future reference.
  422.      */
  423.     switch(uchar(type)){
  424.     case ICMP_DEST_UNREACH:
  425.     case ICMP_TIME_EXCEED:
  426.         tcb->type = type;
  427.         tcb->code = code;
  428.         break;
  429.     case ICMP_QUENCH:
  430.         /* Source quench; cut the congestion window in half,
  431.          * but don't let it go below one packet
  432.          */
  433.         tcb->cwind /= 2;
  434.         tcb->cwind = max(tcb->mss,tcb->cwind);
  435.         break;
  436.     }
  437. }
  438. /* Send an acceptable reset (RST) response for this segment
  439.  * The RST reply is composed in place on the input segment
  440.  */
  441. void
  442. reset(ip,seg)
  443. struct ip *ip;                  /* Offending IP header */
  444. register struct tcp *seg;       /* Offending TCP header */
  445. {
  446.     struct mbuf *hbp;
  447.     struct pseudo_header ph;
  448.     int16 tmp;
  449.  
  450.     if(seg->flags.rst)
  451.         return; /* Never send an RST in response to an RST */
  452.  
  453.     /* Compose the RST IP pseudo-header, swapping addresses */
  454.     ph.source = ip->dest;
  455.     ph.dest = ip->source;
  456.     ph.protocol = TCP_PTCL;
  457.     ph.length = TCPLEN;
  458.  
  459.     /* Swap port numbers */
  460.     tmp = seg->source;
  461.     seg->source = seg->dest;
  462.     seg->dest = tmp;
  463.  
  464.     if(seg->flags.ack){
  465.         /* This reset is being sent to clear a half-open connection.
  466.          * Set the sequence number of the RST to the incoming ACK
  467.          * so it will be acceptable.
  468.          */
  469.         seg->flags.ack = 0;
  470.         seg->seq = seg->ack;
  471.         seg->ack = 0;
  472.     } else {
  473.         /* We're rejecting a connect request (SYN) from TCP_LISTEN state
  474.          * so we have to "acknowledge" their SYN.
  475.          */
  476.         seg->flags.ack = 1;
  477.         seg->ack = seg->seq;
  478.         seg->seq = 0;
  479.         if(seg->flags.syn)
  480.             seg->ack++;
  481.     }
  482.     /* Set remaining parts of packet */
  483.     seg->flags.urg = 0;
  484.     seg->flags.psh = 0;
  485.     seg->flags.rst = 1;
  486.     seg->flags.syn = 0;
  487.     seg->flags.fin = 0;
  488.     seg->wnd = 0;
  489.     seg->up = 0;
  490.     seg->mss = 0;
  491.     seg->optlen = 0;
  492.     if((hbp = htontcp(seg,NULLBUF,&ph)) == NULLBUF)
  493.         return;
  494.     /* Ship it out (note swap of addresses) */
  495.     ip_send(ip->dest,ip->source,TCP_PTCL,ip->tos,0,hbp,ph.length,0,0);
  496.     tcpOutRsts++;
  497. }
  498.  
  499. /* Process an incoming acknowledgement and window indication.
  500.  * From page 72.
  501.  */
  502. static void
  503. update(tcb,seg,length)
  504. register struct tcb *tcb;
  505. register struct tcp *seg;
  506. int16 length;
  507. {
  508.     int16 acked;
  509.     int16 expand;
  510.  
  511.     acked = 0;
  512.     if(seq_gt(seg->ack,tcb->snd.nxt)){
  513.         tcb->flags.force = 1;   /* Acks something not yet sent */
  514.         return;
  515.     }
  516.     /* Decide if we need to do a window update.
  517.      * This is always checked whenever a legal ACK is received,
  518.      * even if it doesn't actually acknowledge anything,
  519.      * because it might be a spontaneous window reopening.
  520.      */
  521.     if(seq_gt(seg->seq,tcb->snd.wl1) || ((seg->seq == tcb->snd.wl1)
  522.      && seq_ge(seg->ack,tcb->snd.wl2))){
  523.         /* If the window had been closed, crank back the
  524.          * send pointer so we'll immediately resume transmission.
  525.          * Otherwise we'd have to wait until the next probe.
  526.          */
  527.         if(tcb->snd.wnd == 0 && seg->wnd != 0)
  528.             tcb->snd.ptr = tcb->snd.una;
  529.         tcb->snd.wnd = seg->wnd;
  530.         tcb->snd.wl1 = seg->seq;
  531.         tcb->snd.wl2 = seg->ack;
  532.     }
  533.     /* See if anything new is being acknowledged */
  534.     if(!seq_gt(seg->ack,tcb->snd.una)){
  535.         if(seg->ack != tcb->snd.una)
  536.             return; /* Old ack, ignore */
  537.  
  538.         if(length != 0 || seg->flags.syn || seg->flags.fin)
  539.             return; /* Nothing acked, but there is data */
  540.  
  541.         /* Van Jacobson "fast recovery" code */
  542.         if(++tcb->dupacks == TCPDUPACKS){
  543.             /* We've had a burst of do-nothing acks, so
  544.              * we almost certainly lost a packet.
  545.              * Resend it now to avoid a timeout. (This is
  546.              * Van Jacobson's 'quick recovery' algorithm.)
  547.              */
  548.             int32 ptrsave;
  549.  
  550.             /* Knock the threshold down just as though
  551.              * this were a timeout, since we've had
  552.              * network congestion.
  553.              */
  554.             tcb->ssthresh = tcb->cwind/2;
  555.             tcb->ssthresh = max(tcb->ssthresh,tcb->mss);
  556.  
  557.             /* Manipulate the machinery in tcp_output() to
  558.              * retransmit just the missing packet
  559.              */
  560.             ptrsave = tcb->snd.ptr;
  561.             tcb->snd.ptr = tcb->snd.una;
  562.             tcb->cwind = tcb->mss;
  563.             tcp_output(tcb);
  564.             tcb->snd.ptr = ptrsave;
  565.  
  566.             /* "Inflate" the congestion window, pretending as
  567.              * though the duplicate acks were normally acking
  568.              * the packets beyond the one that was lost.
  569.              */
  570.             tcb->cwind = tcb->ssthresh + TCPDUPACKS*tcb->mss;
  571.         } else if(tcb->dupacks > TCPDUPACKS){
  572.             /* Continue to inflate the congestion window
  573.              * until the acks finally get "unstuck".
  574.              */
  575.             tcb->cwind += tcb->mss;
  576.         }
  577.         return;
  578.     }
  579.     if(tcb->dupacks >= TCPDUPACKS && tcb->cwind > tcb->ssthresh){
  580.         /* The acks have finally gotten "unstuck". So now we
  581.          * can "deflate" the congestion window, i.e. take it
  582.          * back down to where it would be after slow start
  583.          * finishes.
  584.          */
  585.         tcb->cwind = tcb->ssthresh;
  586.     }
  587.     tcb->dupacks = 0;
  588.  
  589.     /* We're here, so the ACK must have actually acked something */
  590.     acked = seg->ack - tcb->snd.una;
  591.  
  592.     /* Expand congestion window if not already at limit and if
  593.      * this packet wasn't retransmitted
  594.      */
  595.     if(tcb->cwind < tcb->snd.wnd && !tcb->flags.retran){
  596.         if(tcb->cwind < tcb->ssthresh){
  597.             /* Still doing slow start/CUTE, expand by amount acked */
  598.             expand = min(acked,tcb->mss);
  599.         } else {
  600.             /* Steady-state test of extra path capacity */
  601.             expand = ((long)tcb->mss * tcb->mss) / tcb->cwind;
  602.         }
  603.         /* Guard against arithmetic overflow */
  604.         if(tcb->cwind + expand < tcb->cwind)
  605.             expand = MAXINT16 - tcb->cwind;
  606.  
  607.         /* Don't expand beyond the offered window */
  608.         if(tcb->cwind + expand > tcb->snd.wnd)
  609.             expand = tcb->snd.wnd - tcb->cwind;
  610.  
  611.         if(expand != 0){
  612. #ifdef  notdef
  613.             /* Kick up the mean deviation estimate to prevent
  614.              * unnecessary retransmission should we already be
  615.              * bandwidth limited
  616.              */
  617.             tcb->mdev += ((long)tcb->srtt * expand) / tcb->cwind;
  618. #endif
  619.             tcb->cwind += expand;
  620.         }
  621.     }
  622.     /* Round trip time estimation */
  623.     if(tcb->flags.rtt_run && seq_ge(seg->ack,tcb->rttseq)){
  624.         /* A timed sequence number has been acked */
  625.         tcb->flags.rtt_run = 0;
  626.         if(!(tcb->flags.retran)){
  627.             int32 rtt;      /* measured round trip time */
  628.             int32 abserr;   /* abs(rtt - srtt) */
  629.  
  630.             /* This packet was sent only once and now
  631.              * it's been acked, so process the round trip time
  632.              */
  633.             rtt = msclock() - tcb->rtt_time;
  634.  
  635.             abserr = (rtt > tcb->srtt) ? rtt - tcb->srtt : tcb->srtt - rtt;
  636.             /* Run SRTT and MDEV integrators, with rounding */
  637.             tcb->srtt = ((AGAIN-1)*tcb->srtt + rtt + (AGAIN/2)) >> LAGAIN;
  638.             tcb->mdev = ((DGAIN-1)*tcb->mdev + abserr + (DGAIN/2)) >> LDGAIN;
  639.  
  640.             rtt_add(tcb->conn.remote.address,rtt);
  641.             /* Reset the backoff level */
  642.             tcb->backoff = 0;
  643.         }
  644.     }
  645.     tcb->sndcnt -= acked;   /* Update virtual byte count on snd queue */
  646.     tcb->snd.una = seg->ack;
  647.  
  648.     /* If we're waiting for an ack of our SYN, note it and adjust count */
  649.     if(!(tcb->flags.synack)){
  650.         tcb->flags.synack = 1;
  651.         acked--;        /* One less byte to pull from real snd queue */
  652.     }
  653.     /* Remove acknowledged bytes from the send queue and update the
  654.      * unacknowledged pointer. If a FIN is being acked,
  655.      * pullup won't be able to remove it from the queue, but that
  656.      * causes no harm.
  657.      */
  658.     pullup(&tcb->sndq,NULLCHAR,acked);
  659.  
  660.     /* Stop retransmission timer, but restart it if there is still
  661.      * unacknowledged data. If there is no more unacked data,
  662.      * the transmitter has gone at least momentarily idle, so
  663.      * record the time for the VJ restart-slowstart rule.
  664.      */
  665.     stop_timer(&tcb->timer);
  666.     if(tcb->snd.una != tcb->snd.nxt)
  667.         start_timer(&tcb->timer);
  668.     else
  669.         tcb->lastactive = msclock();
  670.  
  671.     /* If retransmissions have been occurring, make sure the
  672.      * send pointer doesn't repeat ancient history
  673.      */
  674.     if(seq_lt(tcb->snd.ptr,tcb->snd.una))
  675.         tcb->snd.ptr = tcb->snd.una;
  676.  
  677.     /* Clear the retransmission flag since the oldest
  678.      * unacknowledged segment (the only one that is ever retransmitted)
  679.      * has now been acked.
  680.      */
  681.     tcb->flags.retran = 0;
  682.  
  683.     /* If outgoing data was acked, notify the user so he can send more
  684.      * unless we've already sent a FIN.
  685.      */
  686.     if(acked != 0 && tcb->t_upcall
  687.      && (tcb->state == TCP_ESTABLISHED || tcb->state == TCP_CLOSE_WAIT)
  688.      && tcb->window > tcb->sndcnt){
  689.         (*tcb->t_upcall)(tcb,tcb->window - tcb->sndcnt);
  690.     }
  691. }
  692.  
  693. /* Determine if the given sequence number is in our receiver window.
  694.  * NB: must not be used when window is closed!
  695.  */
  696. static
  697. int
  698. in_window(tcb,seq)
  699. struct tcb *tcb;
  700. int32 seq;
  701. {
  702.     return seq_within(seq,tcb->rcv.nxt,(int32)(tcb->rcv.nxt+tcb->rcv.wnd-1));
  703. }
  704.  
  705. /* Process an incoming SYN */
  706. static void
  707. proc_syn(tcb,tos,seg)
  708. register struct tcb *tcb;
  709. char tos;
  710. struct tcp *seg;
  711. {
  712.     int16 mtu;
  713.     struct tcp_rtt *tp;
  714.  
  715.     tcb->flags.force = 1;   /* Always send a response */
  716.  
  717.     /* Note: It's not specified in RFC 793, but SND.WL1 and
  718.      * SND.WND are initialized here since it's possible for the
  719.      * window update routine in update() to fail depending on the
  720.      * IRS if they are left unitialized.
  721.      */
  722.     /* Check incoming precedence and increase if higher */
  723.     if(PREC(tos) > PREC(tcb->tos))
  724.         tcb->tos = tos;
  725.     tcb->rcv.nxt = seg->seq + 1;    /* p 68 */
  726.     tcb->snd.wl1 = tcb->irs = seg->seq;
  727.     tcb->snd.wnd = seg->wnd;
  728.     if(seg->mss != 0)
  729.         tcb->mss = seg->mss;
  730.     /* Check the MTU of the interface we'll use to reach this guy
  731.      * and lower the MSS so that unnecessary fragmentation won't occur
  732.      */
  733.     if((mtu = ip_mtu(tcb->conn.remote.address)) != 0){
  734.         /* Allow space for the TCP and IP headers */
  735.         mtu -= TCPLEN + IPLEN;
  736.         tcb->cwind = tcb->mss = min(mtu,tcb->mss);
  737.     }
  738.     /* See if there's round-trip time experience */
  739.     if((tp = rtt_get(tcb->conn.remote.address)) != NULLRTT){
  740.         tcb->srtt = tp->srtt;
  741.         tcb->mdev = tp->mdev;
  742.     }
  743. }
  744.  
  745. /* Generate an initial sequence number and put a SYN on the send queue */
  746. void
  747. send_syn(tcb)
  748. register struct tcb *tcb;
  749. {
  750.     tcb->iss = geniss();
  751.     tcb->rttseq = tcb->snd.wl2 = tcb->snd.una = tcb->iss;
  752.     tcb->snd.ptr = tcb->snd.nxt = tcb->rttseq;
  753.     tcb->sndcnt++;
  754.     tcb->flags.force = 1;
  755. }
  756.  
  757. /* Add an entry to the resequencing queue in the proper place */
  758. static void
  759. add_reseq(tcb,tos,seg,bp,length)
  760. struct tcb *tcb;
  761. char tos;
  762. struct tcp *seg;
  763. struct mbuf *bp;
  764. int16 length;
  765. {
  766.     register struct reseq *rp,*rp1;
  767.  
  768.     /* Allocate reassembly descriptor */
  769.     if((rp = (struct reseq *)malloc(sizeof (struct reseq))) == NULLRESEQ){
  770.         /* No space, toss on floor */
  771.         free_p(bp);
  772.         return;
  773.     }
  774.     ASSIGN(rp->seg,*seg);
  775.     rp->tos = tos;
  776.     rp->bp = bp;
  777.     rp->length = length;
  778.  
  779.     /* Place on reassembly list sorting by starting seq number */
  780.     rp1 = tcb->reseq;
  781.     if(rp1 == NULLRESEQ || seq_lt(seg->seq,rp1->seg.seq)){
  782.         /* Either the list is empty, or we're less than all other
  783.          * entries; insert at beginning.
  784.          */
  785.         rp->next = rp1;
  786.         tcb->reseq = rp;
  787.     } else {
  788.         /* Find the last entry less than us */
  789.         for(;;){
  790.             if(rp1->next == NULLRESEQ || seq_lt(seg->seq,rp1->next->seg.seq)){
  791.                 /* We belong just after this one */
  792.                 rp->next = rp1->next;
  793.                 rp1->next = rp;
  794.                 break;
  795.             }
  796.             rp1 = rp1->next;
  797.         }
  798.     }
  799. }
  800.  
  801. /* Fetch the first entry off the resequencing queue */
  802. static void
  803. get_reseq(tcb,tos,seg,bp,length)
  804. register struct tcb *tcb;
  805. char *tos;
  806. struct tcp *seg;
  807. struct mbuf **bp;
  808. int16 *length;
  809. {
  810.     register struct reseq *rp;
  811.  
  812.     if((rp = tcb->reseq) == NULLRESEQ)
  813.         return;
  814.  
  815.     tcb->reseq = rp->next;
  816.  
  817.     *tos = rp->tos;
  818.     ASSIGN(*seg,rp->seg);
  819.     *bp = rp->bp;
  820.     *length = rp->length;
  821.     free((char *)rp);
  822. }
  823.  
  824. /* Trim segment to fit window. Return 0 if OK, -1 if segment is
  825.  * unacceptable.
  826.  */
  827. static int
  828. trim(tcb,seg,bpp,length)
  829. register struct tcb *tcb;
  830. register struct tcp *seg;
  831. struct mbuf **bpp;
  832. int16 *length;
  833. {
  834.     long dupcnt,excess;
  835.     int16 len;              /* Segment length including flags */
  836.     char accept = 0;
  837.  
  838.     len = *length;
  839.     if(seg->flags.syn)
  840.         len++;
  841.     if(seg->flags.fin)
  842.         len++;
  843.  
  844.     /* Acceptability tests */
  845.     if(tcb->rcv.wnd == 0){
  846.         /* Only in-order, zero-length segments are acceptable when
  847.          * our window is closed.
  848.          */
  849.         if(seg->seq == tcb->rcv.nxt && len == 0){
  850.             return 0;       /* Acceptable, no trimming needed */
  851.         }
  852.     } else {
  853.         /* Some part of the segment must be in the window */
  854.         if(in_window(tcb,seg->seq)){
  855.             accept++;       /* Beginning is */
  856.         } else if(len != 0){
  857.             if(in_window(tcb,(int32)(seg->seq+len-1)) || /* End is */
  858.              seq_within(tcb->rcv.nxt,seg->seq,(int32)(seg->seq+len-1))){ /* Straddles */
  859.                 accept++;
  860.             }
  861.         }
  862.     }
  863.     if(!accept){
  864.         tcb->rerecv += len;     /* Assume all of it was a duplicate */
  865.         free_p(*bpp);
  866.         return -1;
  867.     }
  868.     if((dupcnt = tcb->rcv.nxt - seg->seq) > 0){
  869.         tcb->rerecv += dupcnt;
  870.         /* Trim off SYN if present */
  871.         if(seg->flags.syn){
  872.             /* SYN is before first data byte */
  873.             seg->flags.syn = 0;
  874.             seg->seq++;
  875.             dupcnt--;
  876.         }
  877.         if(dupcnt > 0){
  878.             pullup(bpp,NULLCHAR,(int16)dupcnt);
  879.             seg->seq += dupcnt;
  880.             *length -= dupcnt;
  881.         }
  882.     }
  883.     if((excess = seg->seq + *length - (tcb->rcv.nxt + tcb->rcv.wnd)) > 0){
  884.         tcb->rerecv += excess;
  885.         /* Trim right edge */
  886.         *length -= excess;
  887.         trim_mbuf(bpp,*length);
  888.         seg->flags.fin = 0;     /* FIN follows last data byte */
  889.     }
  890.     return 0;
  891. }
  892.